﻿/**
 * 影片滚动条组件
 * 编写时间:2008/7/10-2008/7/15
 * 修改时间:2010-7-2 16:41
 * 修改内容:
 * ·改变纯代码创建方式
 * ·修正缓动卡住问题
 * ·修正初始化报错
 * ·修改皮肤调用与切换方式
 * ·增加初始坐标自动定位功能
 * by:望月狼
 *
 * @exception
 * McScrollBar针对影片剪辑与遮罩来创建滚动条，采用目标控制方式进行反定位计算，富有高效而精确的优势。
 * 内置上下按钮操作、滚动条示位、轨迹定位、滚轮定位、键盘定位、翻页定位以及皮肤切换功能，水平与垂直滚动切换功能
 * 使用方法：
 * 实例化以后，传入被滚动的影片剪辑和遮罩对象，会通过遮罩的位置与大小自动定位滚动条的位置
 * 皮肤更换方法：
 * 皮肤分为内置皮肤包与外用包，外用皮肤包多加了"_out"链接名
 *
 * 属性说明：
  target:滚动的影片剪辑
  targetMask:设置滚动遮罩
  wheelArea:设置鼠标的滚动区域，值为本类的常量，NO_SCROLL:禁止滚动 MASK_AREA:当鼠标停留在遮罩区域时滚动(默认) ALL_AREA:不管鼠标在任何区域都可滚动
  vertical:是否为水平滚动条 true
  transition:是否使用缓动效果 false
  speed:缓动速度 5
  butVisible:是否使用按钮 true
  hotkey:是否使用键盘控制 上下/左右移动和翻页按钮 true
  delay:滚动刻度 20
  enabled:是否禁止使用，禁用时将隐藏，并进入冷冻模式 false
  freeze:冷冻模式，进入本模式后，将清除各个控制事件,使冻结滚动条各功能但不隐藏 false

  pageCount:总页数
  currentPage:当前页
  face:皮肤切换，直接设为皮肤路径就行了
  autoSize:是否跟据遮罩的大小与位置自动调整滚动条大小和位置,默认为是
  fillIn:自动调整模式中，滚动条是否在遮罩内部填充，默认为是
  autoHide:无滚动区域时，是否自动隐藏，默认为否
  initAdjust:初始化时，是否调整滚动目标的位置，默认为是(应该在添加到舞台之前设置此参数)
 *
 *
 *
 * @example
 *  scrollBar = new McScrollBar
	scrollBar.target = mc;//设置被滚动的显示对象
	scrollBar.targetMask = maskMc;//设置遮罩对象
	addChild(scrollBar)
 * @author wzh (shch8.com)
 * @version	V2.1
 */
package com._public._ui
{
	import com._public._control.ChildCtrl;
	import com._public._debug.ClearMemory;
	import com._public._display.FaceApp;
	
	import flash.display.DisplayObjectContainer;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.ui.Keyboard;

	/**
	 * 影片滚动条组件
	 * by:望月狼
	 * @author wzh (shch8.com)
	 */
	public class McScrollBar extends Sprite
	{
		//常量
		public static var NO_SCROLL:String = "noScroll";//禁止滚动
		public static var ALL_AREA:String = "allArea";//不管鼠标在任何区域都可滚动
		public static var MASK_AREA:String = "maskArea";//当鼠标停留在遮罩区域时滚动
		
		//皮肤使用参数
		private var loader:Loader;
		private var thisDomain:ApplicationDomain
		private var bgRect:Sprite;
		private var upBt:Sprite;
		private var downBt:Sprite;
		private var scrBar:Sprite;
		private var scrIcon:Sprite;
		private var scrSize:Number=100;
		private var maskSize:Number;
		private var bodySize:Number;
		private var maskPos:Number;
		private var bodyPos:Number;
		
		//属性参数
		private var _vertical:Boolean=true;//滚动方式--X轴:false ，Y轴:true
		private var _butVisible:Boolean=true;//是否使用按钮
		private var _hotkey:Boolean=true;//是否使用键盘
		private var _transition:Boolean=false;//是否用缓动
		private var _delay:Number=20;//滚动核度 单位：像素
		private var _wheelArea:String = MASK_AREA;//滚轮感应区域--所有区域 , 滚动区域 , 禁止感应
		private var _speed:Number=5;//缓冲参数
		private var _target:DisplayObjectContainer;
		private var _targetMask:DisplayObjectContainer;
		private var _face:String="";
		private var _currentPage:Number;//当前所在页
		private var _pageCount:Number;//总页数
		private var _autoSize:Boolean = true;//是否跟据遮罩的大小自动调整滚动条大小的位置
		private var _fillIn:Boolean=true;//自动调整模式中，滚动条是否在遮罩内部填充
		private var _autoHide:Boolean=false;//无滚动区域时，是否自动隐藏
		private var _initAdjust:Boolean = true;//初始化时，是否调整滚动目标的位置
		private var _enabled:Boolean = true;//是否禁止使用，禁用时将隐藏，并进入冷冻模式
		private var _freeze:Boolean;//冷冻模式，进入本模式后，将清除各个控制事件,使冻结滚动条各功能但不隐藏
		//内用参数
		private var sizeEvent:Boolean;//滚动条是否感应影片变化
		private var sizeEvent_tween:Boolean;//于缓动时判断能否启动感应机制
		private var scrollRun:Boolean;//自动滚动是否执行
		private var mouseStatus:String;//鼠标状态，记录按钮中所处状态 over,out,up,down
		private var pasObj:String;//当前鼠标操作的按钮 up,down,bar
		private var pasTime:Number;//点上下菜单时，按住时间，控制其连续滚动
		private var bodyRevise:Number;//_target的修正值，图形不在0坐标中时修正
		private var maskRevise:Number;//_targetMask的修正值，图形不在0坐标中时修正
		private var installEnd:Boolean
		private var scrollScrNum:Number;//缓动参数缓存
		private var _tweening:Boolean;//缓动机制是否正在执行
		private var activeFace:Boolean;//是否为动态皮肤
		private var tweenInstall:Boolean;//换肤时禁用缓动模式
		private var btUpH:Number=0;//向上按钮高度
		private var btDownH:Number = 0;//向下按钮高度
		private var dragStartY:uint;//滚动条按下拖动时，所点击的Y轴
		//皮肤常量
		private const ScrollBarUp_upSkin:String = "ScrollBarUp_upSkin"
		private const ScrollBarUp_overSkin:String = "ScrollBarUp_overSkin"
		private const ScrollBarUp_downSkin:String = "ScrollBarUp_downSkin"
		private const ScrollBarUp_disabledSkin:String = "ScrollBarUp_disabledSkin"
		
		private const ScrollBarDown_upSkin:String = "ScrollBarDown_upSkin"
		private const ScrollBarDown_overSkin:String = "ScrollBarDown_overSkin"
		private const ScrollBarDown_downSkin:String = "ScrollBarDown_downSkin"
		private const ScrollBarDown_disabledSkin:String = "ScrollBarDown_disabledSkin"
		
		private const ScrollBarTrack_skin:String = "ScrollBarTrack_skin"
		private const ScrollBarIcon_thumbIcon:String = "ScrollBarIcon_thumbIcon"
		
		private const ScrollBarThumb_upSkin:String = "ScrollBarThumb_upSkin"
		private const ScrollBarThumb_downSkin:String = "ScrollBarThumb_downSkin"
		private const ScrollBarThumb_overSkin:String = "ScrollBarThumb_overSkin"
		
		public function McScrollBar() {
			this.addEventListener(Event.ADDED_TO_STAGE, init);
			scrSize = scrSize / this.scaleY;
		}
		private function init(event:Event=null):void
		{
			if (event == null && stage == null) return;
			if(!existFace)trace("未找到滚动条皮肤!")
			if (targetMask == null || target == null || !existFace||stage==null) return;
			setSprite();
			if (!installEnd) {
					super.x = _targetMask.x + _targetMask.width;
					if(vertical){
					this.y = _targetMask.y;
					this.height = _targetMask.height;
					super.x =super.x-fillArea;
					}else {
						this.y = _targetMask.y + _targetMask.height-fillArea
						this.height = _targetMask.width
						}
				
			installEnd = true;
			this.addEventListener(Event.ENTER_FRAME, enterFrame);
			breakScr();
			}else {
				tweenInstall = true;
				breakBody();
				}
			freeze = _freeze;
		}
		/*冷冻模式，进入本模式后，将清除各个控制事件,使冻结滚动条各功能但不隐藏*/
		public function get freeze():Boolean { return _freeze };
		public function set freeze(value:Boolean):void
		{
			_freeze = value;
			if (value) {
					this.removeEventListener(Event.ENTER_FRAME, enterFrame);
					if(upBt){
						upBt.removeEventListener(MouseEvent.MOUSE_OVER,upOver_fun);
						upBt.removeEventListener(MouseEvent.MOUSE_OUT,upOut_fun);
						upBt.removeEventListener(MouseEvent.MOUSE_DOWN, upDown_fun);
						downBt.removeEventListener(MouseEvent.MOUSE_OVER,downOver_fun);
						downBt.removeEventListener(MouseEvent.MOUSE_OUT,downOut_fun);
						downBt.removeEventListener(MouseEvent.MOUSE_DOWN,downDown_fun);
					}
					if(bgRect){
						bgRect.removeEventListener(MouseEvent.MOUSE_DOWN,bgDown);
						bgRect.removeEventListener(MouseEvent.MOUSE_OUT, bgOut);
					}
					if(scrBar){
					scrBar.removeEventListener(MouseEvent.MOUSE_OVER,barOver_fun);
					scrBar.removeEventListener(MouseEvent.MOUSE_OUT,barOut_fun);
					scrBar.removeEventListener(MouseEvent.MOUSE_DOWN, barDown_fun);
					}
					if (stage) {
						stage.removeEventListener(MouseEvent.MOUSE_MOVE,stageMouseMove);
						stage.removeEventListener(MouseEvent.MOUSE_UP, stageMouseUp);
						if (hotkey)
							stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownFun);
						setWheelEvent(false)
					}
				}else {
					this.addEventListener(Event.ENTER_FRAME, enterFrame);
					if(upBt){
						upBt.addEventListener(MouseEvent.MOUSE_OVER,upOver_fun);
						upBt.addEventListener(MouseEvent.MOUSE_OUT,upOut_fun);
						upBt.addEventListener(MouseEvent.MOUSE_DOWN, upDown_fun);
						downBt.addEventListener(MouseEvent.MOUSE_OVER,downOver_fun);
						downBt.addEventListener(MouseEvent.MOUSE_OUT,downOut_fun);
						downBt.addEventListener(MouseEvent.MOUSE_DOWN,downDown_fun);
					}
					if(bgRect){
						bgRect.addEventListener(MouseEvent.MOUSE_DOWN,bgDown);
						bgRect.addEventListener(MouseEvent.MOUSE_OUT, bgOut);
					}
					if(scrBar){
					scrBar.addEventListener(MouseEvent.MOUSE_OVER,barOver_fun);
					scrBar.addEventListener(MouseEvent.MOUSE_OUT,barOut_fun);
					scrBar.addEventListener(MouseEvent.MOUSE_DOWN, barDown_fun);
					}
					if (stage) {
						stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUp);
						if (hotkey)
							stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownFun);
						setWheelEvent()
					}
					}
		}
		/*设置滚动遮罩*/
		public function set targetMask(value:DisplayObjectContainer):void { _targetMask = value;if (!installEnd) init();};
		public function get targetMask():DisplayObjectContainer { return _targetMask; };
		/*设置被滚动的影片剪辑*/
		public function set target(value:DisplayObjectContainer):void { _target = value; if (!installEnd) init(); };
		public function get target():DisplayObjectContainer { return _target; };
		
		//是否跟据遮罩的大小自动调整滚动条大小的位置
		public function set autoSize(value:Boolean):void { _autoSize = value; };
		public function get autoSize():Boolean {return _autoSize};
		
		//是否为水平滚动条
		public function set vertical(value:Boolean):void { _vertical = value;if(installEnd){ installEnd = false;refresh();} };
		public function get vertical():Boolean {return _vertical};
		//是否使用缓动效果
		public function set transition(value:Boolean):void { _transition = value;};
		public function get transition():Boolean { return _transition };
		
		//无滚动区域时，是否自动隐藏
		public function set autoHide(value:Boolean):void { _autoHide = value;breakScr()};
		public function get autoHide():Boolean { return _autoHide };
		
		//是否禁止使用
		public function set enabled(value:Boolean):void { _enabled = value;this.visible=value};
		public function get enabled():Boolean { return _enabled };
		
		//初始化时，是否调整滚动目标的位置
		public function set initAdjust(value:Boolean):void { _initAdjust = value;};
		public function get initAdjust():Boolean { return _initAdjust };
		
		//自动调整模式中，滚动条是否在遮罩内部填充
		public function set fillIn(value:Boolean):void { _fillIn = value;};
		public function get fillIn():Boolean { return _fillIn };
		
		//是否使用按钮
		public function set butVisible(value:Boolean):void { _butVisible = value;
		refresh();
		};
		public function get butVisible():Boolean { return _butVisible };
		
		//是否使用键盘控制
		public function set hotkey(value:Boolean):void {
			_hotkey = value;
			if (stage)
			if(_hotkey){
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownFun);
			}else {
				stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownFun);
				}
			};
		public function get hotkey():Boolean {return _hotkey};
		
		/**滚动刻度 单位：像素 默认为20*/
		public function set delay(value:Number):void { _delay = value;};
		public function get delay():Number { return _delay };
		
		//缓动速度，值域为1~10，值越大速度越快,默认为5
		public function set speed(value:Number):void {if (value < 1) value = 1;if (value > 10) value = 10;_speed = 10-value;};
		public function get speed():Number { return _speed };
		
		//设置鼠标的滚动区域，值为本类的常量，NO_SCROLL:禁止滚动 MASK_AREA:当鼠标停留在遮罩区域时滚动(默认) ALL_AREA:不管鼠标在任何区域都可滚动
		public function set wheelArea(value:String):void {
			_wheelArea = value;
			setWheelEvent()
			};
		public function get wheelArea():String { return _wheelArea };
		//总页数
		public function get pageCount():uint { return _pageCount-1 };
		//当前页
		public function get currentPage():uint { return _currentPage };
		public function set currentPage(value:uint):void
		{
			if (value < 1) value = 1;
			if (value > _pageCount) value = _currentPage;
			_currentPage = value;
			var setNum:Number = ( -1 * (value - 1) * maskSize) - bodyRevise + maskPos;
			var limNum:Number = getBodyLim(true);
				if (setNum-limNum>-1) {
					setNum=limNum;
				}
				limNum = getBodyLim(false);
				if (setNum-limNum<3) {
					setNum=limNum;
				}
			tweenFilter(setNum);
			};
		
		public override function set height(_var:Number):void { scrSize = _var; if (stage == null) return; if (existFace && installEnd) { breakScr(); breakBody(); }; };
		public override function set width(_var:Number):void { scrSize = _var; if (stage == null) return; if (existFace && installEnd) { breakScr(); breakBody(); }; };
		public override function get height():Number {if (_vertical)return scrSize; return bgRect.width;};
		public override function get width():Number {if (_vertical)return bgRect.width;return scrSize;};
		override public function get x():Number { var getX:Number = super.x; if (!vertical) getX -= Math.round(width); return getX; };
		override public function set x(value:Number):void { if (vertical) { super.x = value; } else { super.x = value + width; }};
		
		/*皮肤设置,为SWF的调用路径,空字符时,视为默认皮肤还原*/
		public function get face():String { return _face };
		public function set face(value:String):void {
			if (value == null) return;
			_face = value;
			if (value=="") {//皮肤还原
				thisDomain = stage.loaderInfo.applicationDomain;
				activeFace = false;
				refresh();
			} else {
				loader=new Loader();
				loader.load(new URLRequest(value));
				loader.contentLoaderInfo.addEventListener(Event.COMPLETE, mcLoaded);
				loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,swfLoadError);
			}
		}
		/*使用ApplicationDomain方式设置皮肤*/
		public function get faceDomain():ApplicationDomain{return thisDomain}
		public function set faceDomain(value:ApplicationDomain):void { thisDomain = value }
		
		//是否正在缓动，弥补拖动结束时滚动条被反定位
		private function set tweening(value:Boolean):void
		{
			_tweening = value; if (value) return;
			if (vertical) { _target.y = scrollScrNum; } else { _target.x = scrollScrNum; };
			if (sizeEvent_tween) { sizeEvent_tween = false; sizeEvent = true; };
		}
		//皮肤是否存在,不存在则不进行初始化
		private function get existFace():Boolean { return createClip("ScrollBarUp_upSkin") && createClip("ScrollBarTrack_skin") };
		private function get fillArea():Number { if (_fillIn) { return bgRect.width } else { return 0 }};
		private function refresh():void
		{
			ChildCtrl.getInstance().removeAll(this)
			bgRect = upBt = downBt = scrBar = scrIcon = null;
			this.removeEventListener(Event.ENTER_FRAME, enterFrame);
			init()
		}
		
		private function enterFrame(e:Event):void {
			if (sizeEvent) {
				if (vertical) {
					if (bodySize!=Math.round(_target.height)||maskSize!=Math.round(_targetMask.height)||maskPos!=Math.round(_targetMask.y+maskRevise)||bodyPos!=Math.round(_target.y+bodyRevise)) {
						if (_autoSize) {
							if (maskSize != Math.round(_targetMask.height) || maskPos != Math.round(_targetMask.y + maskRevise)) {
								this.height = _targetMask.height;
								this.y = _targetMask.y
							}
						}
						setVars(); breakScr();
					}
					if (_autoSize)if (int(_targetMask.x+_targetMask.width)!=int(this.x+fillArea)) {
							this.x = _targetMask.x + _targetMask.width-fillArea;
							}
				} else {
					if (bodySize!=Math.round(_target.width)||maskSize!=Math.round(_targetMask.width)||maskPos!=Math.round(_targetMask.x+maskRevise)||bodyPos!=Math.round(_target.x-bodyRevise)) {
						if (_autoSize){
							if (maskSize!=Math.round(_targetMask.width)||maskPos!=Math.round(_targetMask.x+maskRevise)) {
								setVars();
								this.height = _targetMask.width
								super.x = _targetMask.x + this.height
							}
						}else{
							setVars(); breakScr();
							}
					}
					if (_autoSize)if (int(_targetMask.y+_targetMask.height)!=int(this.y+fillArea)) {
							this.y = _targetMask.y + _targetMask.height - fillArea;
							}
				}
			}
			if(_tweening)
			if (vertical) {
					_target.y += (scrollScrNum - _target.y) / _speed;
					if (int(_target.y/2) == int(scrollScrNum/2)) tweening = false;
				}else {
					_target.x += (scrollScrNum - _target.x) / _speed;
					if (int(_target.x/2) == int(scrollScrNum/2)) tweening = false;
					}
					
			if (pasTime != 0) {
				pasTime--;
				if (pasTime==0) {
					if (_target&& _targetMask) {
						if (_target.mask==null) {setSprite();} else {scrollRun = true;}
					}
				}
			}
			if (scrollRun) {
				if (pasObj=="down")scrollBody(0,delay,false);
				if (pasObj=="up")scrollBody(0,delay,true);
				if (pasObj=="bgRect")bgDown(null,false);
			}
		}
		/*初始皮肤设置*/
		private function setSprite():void {
			if (_target&& _targetMask) {
				_target.mask=_targetMask;
				sizeEvent = true;
				if (bgRect != null) {
					return
					}
				bgRect=createClip("ScrollBarTrack_skin");
				bgRect.addEventListener(MouseEvent.MOUSE_DOWN,bgDown);
				bgRect.addEventListener(MouseEvent.MOUSE_OUT, bgOut);
				if (bgRect!=null) {
					this.addChild(bgRect);
					bgRect.height=scrSize;
				}
				if (butVisible) {
					addButton("ScrollBarUp_disabledSkin","up");
					addButton("ScrollBarUp_disabledSkin","down");
				}
				if (!vertical) {
					this.rotation=90;
				}else {
					this.rotation=0;
					}
				
				setVars();
				if(_initAdjust&&!installEnd)
				if (vertical) {
					_target.y=getBodyLim(true);
				} else {
					_target.x=getBodyLim(true);
				}
				if (bodySize>=maskSize) {
					if (scrBar!=null) {
						removeChild(scrBar);
					}
				}
					if (hotkey)stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownFun);
					setWheelEvent()
					breakScr();
			}
		}
		private function setWheelEvent(isAdd:Boolean=true):void {
			if (isAdd) {
				if (wheelArea == ALL_AREA) {
					if(stage)stage.addEventListener(MouseEvent.MOUSE_WHEEL,wheelFun);
				}else if (wheelArea == MASK_AREA){
					target.addEventListener(MouseEvent.MOUSE_WHEEL,wheelFun);
					}
				if(wheelArea!=NO_SCROLL)this.addEventListener(MouseEvent.MOUSE_WHEEL,wheelFun);
			}else {
				if(stage)stage.removeEventListener(MouseEvent.MOUSE_WHEEL,wheelFun);
				target.removeEventListener(MouseEvent.MOUSE_WHEEL,wheelFun);
				this.addEventListener(MouseEvent.MOUSE_WHEEL,wheelFun);
			}
		}
		/**
		 * 正则滚动，于主体
		 * @param	setTime 进入连续模式的间隔时间
		 * @param	_scrNum 滚动值
		 * @param	scrollUp 方向
		 **/
		private function scrollBody(setTime:Number=10,_scrNum:Number=0,scrollUp:Boolean=true):void {
			var setY:Number;
			var minY:Number;
			var _targetY:Number;
			if (sizeEvent_tween) {
				sizeEvent_tween = false;
				sizeEvent = true;
			}
			if (_scrNum==0) {
				_scrNum=delay;
			}
			if (vertical) {
				_targetY=_target.y;
			} else {
				_targetY = _target.x;
				
				scrollUp=!scrollUp;//水平滚动,反转
			}
			if (_tweening)_targetY = scrollScrNum;//正在缓动，则使用缓动终值进行计算
			if (scrollUp) {
				setY=_targetY+_scrNum;
				minY=getBodyLim(true);
				if (setY>minY) {
					setY=minY;
				}
			} else {
				setY=_targetY-_scrNum;
				minY=getBodyLim(false);
				if (setY<minY) {
					setY=minY;
				}
			}
			tweenFilter(setY);
			pasTime=setTime;
		}
		/*滚动效果*/
		private function tweenFilter(setNum:Number):void {
			if (!_transition || tweenInstall) {
				tweenInstall = false;
				if (vertical) {
					_target.y = setNum;
				}else {
					_target.x = setNum;
					}
					return;
				}
			scrollScrNum = setNum;
			_tweening = true;
		}
		/*滚动条滚动时刷新主体*/
		private function breakBody():void {
			if (scrBar == null) return;
			var scrArea:Number=scrSize-scrBar.height;
			var thenY:Number = scrBar.y;
			if (butVisible) {
				thenY-=upBt.height;
				scrArea-=upBt.height;
				scrArea-=downBt.height;
			}
			if (!vertical) {//横向滚动时，滚动条位置效果相反
				thenY=scrArea-thenY;
			}
			var scale:Number=(bodySize-maskSize)/scrArea;
			var setNum:Number=scale*thenY;
			var limNum:Number;
			if (vertical) {
				setNum=-1*setNum+_targetMask.y+maskRevise-bodyRevise;
				limNum=getBodyLim(true);
				if (setNum-limNum>-1) {
					setNum=limNum;
				}
				limNum = getBodyLim(false);
				if (setNum-limNum<3) {
					setNum=limNum;
				}
				tweenFilter(setNum);
			} else {
				setNum=-1*setNum+_targetMask.x+maskRevise-bodyRevise;
				limNum = getBodyLim(true);
				
				_target.x=setNum;
			}
		}
		/*滚动条反滚动，于bar*/
		private function breakScr():void {
			if(stage==null)return
			var mb_dis:Number;
			var scale:Number;
			var setY:Number;
			var setHei:Number;
			
			if (maskSize>=bodySize) {
				if (scrBar!=null) {
					removeChild(scrBar);
					scrBar=null;
				}
				if (scrIcon!=null) {
					removeChild(scrIcon);
					scrIcon=null;
				}
				
				if (butVisible) {
					addButton("ScrollBarUp_disabledSkin","up");
					addButton("ScrollBarUp_disabledSkin","down");
				}
				if (bgRect) bgRect.height = scrSize;
				if (_autoHide&&enabled) {
					if(visible){
					this.visible = false;
					dispatchEvent(new Event(Event.CLOSE));
					target.y = targetMask.y;
					}
				}
				return;
			}
			if (!this.visible&&enabled) {
				this.visible = true;
				this.freeze=false
				dispatchEvent(new Event(Event.OPEN));
				}
			if (scrBar==null) {
				addButton("ScrollBarThumb_upSkin","bar");
				addButton("ScrollBarIcon_thumbIcon","icon");
				if (butVisible) {
					addButton("ScrollBarUp_upSkin","up");
					addButton("ScrollBarDown_upSkin","down");
				}
			}
			
			var scrArea:Number;
			if (butVisible) {
				if (upBt==null) {
					addButton("ScrollBarUp_upSkin","up");
					addButton("ScrollBarDown_upSkin","down");
				}
				scrArea = scrSize - downBt.height - upBt.height;
				downBt.y=scrSize-downBt.height;
			} else {
				scrArea=scrSize;
			}
			setHei=Math.round((maskSize/bodySize)*scrArea);
			if (setHei<10) {
				setHei=10;
			}
			scrBar.height = setHei;
			bgRect.height = scrSize;
			scale=(scrArea-scrBar.height)/(bodySize-maskSize);//区里一个刻度对应滚动条的值
			mb_dis=maskPos-bodyPos;//可滚长度
			if (mb_dis<0) {
				mb_dis=0;
			}
			if (mb_dis>bodySize-maskSize) {
				mb_dis=bodySize-maskSize;
			}
			setY=mb_dis*scale;
			if (butVisible) {
				setY+=upBt.height;
			}
			if (!vertical) {
				setY=scrSize-scrBar.height-setY;
			}
			scrBar.y=setY;
			setScrIcon();
		}
		/*获取可滚的最大值和最小值*/
		private function getBodyLim(getMin:Boolean=true):Number {
			var va:Number;
			if (getMin) {//往下最小值,理想为:0
					va=maskPos  - bodyRevise//主体与遮罩对齐的值
					return va;
			} else {
					va=bodySize - maskSize - maskPos + bodyRevise;
					return va * -1;
			}
			return 0;
		}
		/*修正所用皮肤非原点值的情况*/
		private function setVars():void {
			if (vertical) {
				bodyRevise=Math.round(_target.getBounds(_target).y*_target.scaleY);
				maskRevise=Math.round(_targetMask.getBounds(_targetMask).y*_targetMask.scaleY);
				bodySize=Math.round(_target.height);
				bodyPos=Math.round(_target.y+bodyRevise);
				maskSize=Math.round(_targetMask.height);
				maskPos=Math.round(_targetMask.y+maskRevise);
			} else {
				bodyRevise=Math.round(_target.getBounds(_target).x*_target.scaleX);
				maskRevise=Math.round(_targetMask.getBounds(_targetMask).x*_targetMask.scaleX);
				bodySize=Math.round(_target.width);
				bodyPos=Math.round(_target.x+bodyRevise);
				maskSize=Math.round(_targetMask.width);
				maskPos=Math.round(_targetMask.x+maskRevise);
			}
			_pageCount=Math.round(bodySize/maskSize);
			if (bodySize%maskSize>5) {
				_pageCount++;
			}
			_currentPage=Math.abs(Math.round(((bodyPos+bodyRevise*2)-maskPos-maskSize/5)/maskSize))+1;//当前页计算,页眉留滚动区长度的20%
			//trace(_pageCount+":"+_currentPage+":"+bodySize);
		}
		private function setScrIcon():void {
			if (scrIcon!=null) {
				scrIcon.y=Math.round(scrBar.y+scrBar.height/2-scrIcon.height/2);
				scrIcon.x=(scrBar.width-scrIcon.width)/2;
			}
		}
		private function addButton(buttName:String,sort:String="up"):void {
			if (sort=="up") {
				if (upBt!=null) {
					removeChild(upBt);
				}
				upBt=createClip(buttName);
				if (upBt!=null) {
					this.addChild(upBt);
				}
				upBt.name=sort;
				if (maskSize<bodySize) {
					upBt.addEventListener(MouseEvent.MOUSE_OVER,upOver_fun);
					upBt.addEventListener(MouseEvent.MOUSE_OUT,upOut_fun);
					upBt.addEventListener(MouseEvent.MOUSE_DOWN,upDown_fun);
				}
			}
			if (sort=="down") {
				if (downBt!=null) {
					removeChild(downBt);
				}
				downBt=createClip(buttName);
				if (downBt!=null) {
					this.addChild(downBt);
					downBt.y=scrSize-downBt.height;
				}
				downBt.name=sort;
				if (maskSize<bodySize) {
					downBt.addEventListener(MouseEvent.MOUSE_OVER,downOver_fun);
					downBt.addEventListener(MouseEvent.MOUSE_OUT,downOut_fun);
					downBt.addEventListener(MouseEvent.MOUSE_DOWN,downDown_fun);
				}
			}
			if (sort=="bar") {
				var setY_b:Number=0;
				var setHei_b:Number;
				if (scrBar!=null) {
					setY_b=scrBar.y;
					setHei_b=scrBar.height;
					removeChild(scrBar);
				}
				scrBar=createClip(buttName);
				if (scrBar!=null) {
					this.addChild(scrBar);
					scrBar.y=setY_b;
					scrBar.height=setHei_b;
					if (scrIcon!=null) {
						if (getChildIndex(scrIcon)<getChildIndex(scrBar)) {
							swapChildren(scrIcon,scrBar);
						}
					}
					scrBar.name=sort;
					if (maskSize<bodySize) {
						scrBar.addEventListener(MouseEvent.MOUSE_OVER,barOver_fun);
						scrBar.addEventListener(MouseEvent.MOUSE_OUT,barOut_fun);
						scrBar.addEventListener(MouseEvent.MOUSE_DOWN,barDown_fun);
					}
				}
			}
			if (sort=="icon") {
				if (scrIcon!=null) {
					removeChild(scrIcon);
				}
				scrIcon=createClip(buttName);
				if (scrIcon != null) {
					scrIcon.mouseEnabled = false;
					this.addChild(scrIcon);
				}
			}
		}
		private function keyDownFun(event:KeyboardEvent):void {
			if (!hotkey||maskSize>=bodySize) {
				return;
			}
			var thekey:uint=event.keyCode;
			var setNum:Number;
			var limNum:Number;
			switch (thekey) {
				case 36 ://home
					setNum=getBodyLim(true);
					break;
				case 35 ://end
					setNum=getBodyLim(false);
					break;
				case 33 ://pageUp
					if (_currentPage>1) {
						setNum=(-1*(_currentPage-2)*maskSize)-bodyRevise+maskPos;
						limNum=getBodyLim(true);
						if (setNum>limNum) {
							setNum=limNum;
						}
					}
					break;
				case 34 ://pageDown
					if (_currentPage<_pageCount) {
						setNum=(-1*(_currentPage)*maskSize)-bodyRevise+maskPos;
						limNum=getBodyLim(false);
						if (setNum<limNum) {
							setNum=limNum;
						}
					}
					break;
				case 40 ://down
					if(vertical)scrollBody(0,delay*2,false);
					break;
				case 38 ://up
					if(vertical)scrollBody(0,delay*2,true);
					break;
				case 37 ://right
					if(!vertical)scrollBody(0,delay*2,false);
					break;
				case 39 ://left
					if(!vertical)scrollBody(0,delay*2,true);
					break;
			}
			if (String(setNum)!="NaN") {
				tweenFilter(setNum);
			}
		}
		private function stageMouseUp(e:MouseEvent = null):void {
			if (mouseStatus != "down") return;
			if (bodySize<=maskSize) {
				return;
				}
			mouseStatus="up";
			scrollRun=false;//清除自动滚动
			pasTime=0;
			var objName:String=pasObj;
			pasObj = "";
			
			if (objName == "bar" || objName == null) {
				setVars();
				addButton("ScrollBarThumb_upSkin", "bar");
				//scrBar.stopDrag()
				stage.removeEventListener(MouseEvent.MOUSE_MOVE,stageMouseMove);
				mouseStatus = "bar"
				if (_tweening) {
					sizeEvent_tween = true;
				}else {
					sizeEvent = true;
					}
			}
			if (objName == "bgRect") {
				if (_tweening) {
					sizeEvent_tween = true;
				}else {
					sizeEvent = true;
					}
				}
			if (objName=="up") {
				addButton("ScrollBarUp_upSkin","up");
			}
			if (objName == "down") {
				addButton("ScrollBarDown_upSkin","down");
			}
			//ClearMemory.getInstance().runClear();
		}
		private function stageMouseMove(e:MouseEvent):void {
			breakBody();
			setScrIcon();
			var endY:Number = scrSize - btDownH - scrBar.height;
			var setY:Number = this.mouseY-dragStartY
			if (setY < this.btUpH) setY = btUpH;
			if (setY > endY) setY = endY;
			scrBar.y=setY
		}
		private function wheelFun(e:MouseEvent):void {
			var scrBox:McScrollBar = this;
			if (stage == null || scrBar == null||!(e is MouseEvent)) return;
			if (ifOr()) {
				if (e.delta>0) {
					scrollBody(0,delay*2,true);
				} else {
					scrollBody(0,delay*2,false);
				}
			}
			function ifOr():Boolean {
				if (maskSize>=bodySize) {
					return false;
				}
				if (wheelArea==ALL_AREA) {
					return true;
				} else if (wheelArea==MASK_AREA) {
					if (_targetMask.hitTestPoint(stage.mouseX,stage.mouseY)||scrBox.hitTestPoint(stage.mouseX,stage.mouseY)) {
						return true;
					} else {
						return false;
					}
				} else if (wheelArea==NO_SCROLL) {
					return false;
				}
				return false;
			}
			scrBox=null
		}
		private function bgDown(e:MouseEvent,_setTime:Boolean=true):void {
			if (maskSize>=bodySize) {
				return;
			}
			sizeEvent = false;
			var setAddNum:Number=delay;
			if (_setTime) {
				pasTime=10;
				pasObj="bgRect";
			}
			mouseStatus = "down";
			var setY:Number=this.mouseY;
			if (scrBar.y<setY) {//内容往下滚，滚动条往上滚
				if (setY<=scrBar.y+scrBar.height+setAddNum) {
					stageMouseUp();//超线，清除感应
					setY=this.mouseY-scrBar.height+scrBar.height/2;
				} else {
					setY=scrBar.y+setAddNum;
				}
			} else {
				if (setY>=scrBar.y-setAddNum) {
					setY-=scrBar.height/2;
					stageMouseUp();//超线，清除感应
				} else {
					setY=scrBar.y-setAddNum;
				}
			}
			btUpH=0;
			if (butVisible) {
				btUpH=upBt.height;
			}
			var maxY:Number=scrSize-btUpH-scrBar.height;
			if (setY>maxY) {
				setY=maxY;
			}
			if (setY<btUpH) {
				setY=btUpH;
			}
			scrBar.y=setY;
			breakBody();
			setScrIcon();
		}
		private function bgOut(e:MouseEvent):void {
			if (pasObj=="bgRect") {
				stageMouseUp();
			}
		}
		private function barOver_fun(e:MouseEvent):void {
			if (mouseStatus!="over"&&mouseStatus!="down") {
				mouseStatus="over";
				addButton("ScrollBarThumb_overSkin","bar");
				pasObj="bar";
			}
		}
		private function barOut_fun(e:MouseEvent):void {
			if (mouseStatus!="out"&&mouseStatus!="down") {
				mouseStatus="out";
				addButton("ScrollBarThumb_upSkin","bar");
			}
		}
		private function barDown_fun(e:MouseEvent):void {
			if (mouseStatus!="down") {
				mouseStatus="down";
				addButton("ScrollBarThumb_downSkin","bar");
				if (butVisible) {
					if (upBt!=null) {
						btUpH=upBt.height;
					}
					if (downBt!=null) {
						btDownH=downBt.height;
					}
				}
				var theRec:Rectangle = new Rectangle(0, btUpH,0, scrSize-btDownH-btUpH-scrBar.height);//x=0 y=0 w=200 h=0
				//scrBar.startDrag(false, theRec);//是否锁定中点：false 限制拖动矩形：theRec
				dragStartY=scrBar.mouseY*scrBar.scaleY
				stage.addEventListener(MouseEvent.MOUSE_MOVE,stageMouseMove);
				sizeEvent = false;
				theRec=null
			}
		}
		private function downOver_fun(e:MouseEvent):void {
			if (mouseStatus!="over"&&mouseStatus!="down") {
				mouseStatus="over";
				addButton("ScrollBarDown_overSkin","down");
				pasObj="down";
			}
		}
		private function downOut_fun(e:MouseEvent):void {
			if (mouseStatus!="out"&&mouseStatus!="down") {
				mouseStatus="out";
				addButton("ScrollBarDown_upSkin","down");
			}
		}
		private function downDown_fun(e:MouseEvent):void {
			if (mouseStatus!="down") {
				mouseStatus="down";
				addButton("ScrollBarDown_downSkin","down");
				scrollBody(10,delay,false);
			}
		}
		private function upOver_fun(e:MouseEvent):void {
			if (mouseStatus!="over"&&mouseStatus!="down") {
				mouseStatus="over";
				addButton("ScrollBarUp_overSkin","up");
				pasObj="up";
			}
		}
		private function upOut_fun(e:MouseEvent):void {
			if (mouseStatus!="out"&&mouseStatus!="down") {
				mouseStatus="out";
				addButton("ScrollBarUp_upSkin","up");
			}
		}
		private function upDown_fun(e:MouseEvent):void {
			if (mouseStatus!="down") {
				mouseStatus="down";
				addButton("ScrollBarUp_downSkin","up");
				scrollBody(10,delay,true);
			}
		}
		private function swfLoadError(e:IOErrorEvent):void { throw("皮肤文件加载失败!"); };
		private function mcLoaded(e:Event):void {
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, mcLoaded);
			loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, swfLoadError);
			thisDomain = e.target.applicationDomain;
			activeFace = true;
			refresh();
			//皮肤切换成功,刷新显示
		}
		private function createClip(className:String):Sprite {//跟据类名创建对象,如果有动态皮肤类名后加"_out"
			var clip:Sprite;
			if (thisDomain == null) {
				if (loaderInfo == null) {
					if (stage) {
						thisDomain = stage.loaderInfo.applicationDomain;
					}else {
						throw("找不到皮肤源!")
						}
					}else {
						
					thisDomain = loaderInfo.applicationDomain;
					}
			}
			if (activeFace) {
				clip=FaceApp.createMc(className + "_out",thisDomain);
				if (clip==null) {
					clip=FaceApp.createMc(className,thisDomain);
				}
			} else {
				clip=FaceApp.createMc(className,thisDomain);
			}
			return clip;
		}
	}
}
